package thread;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 25397
 * Date: 2022-04-01
 * Time: 22:19
 */
class MyBlockingQueue{
    //保存数据的本体
    private int[] data=new int[1000];
    //有效元素个数
    private int size=0;
    //队首下标
    private int head=0;
    //队尾下标
    private int tail=0;

    //专门的锁对象
    private Object locker=new Object();

    //入队列
    public void put(int value) throws InterruptedException {
        synchronized (locker){
            if(size== data.length){
                locker.wait();//队列满了
                //哪个对象加锁，就针对哪个对象wait
            }
            //队列不满，就把新元素放到tail位置上
            data[tail]=value;
            tail++;
            //处理tail到达数组末尾的情况
            if(tail>=data.length){
                tail=0;
            }//这里的if也可以直接写tail=tail%data.length，效果一样
            size++;
            //如果入队列成功，则队列非空，就唤醒take中的阻塞等待
            locker.notify();
        }
    }

    //出队列
    public Integer take() throws InterruptedException {
        synchronized (locker){
            if(size==0){//为空不能出
                locker.wait();
            }
            //不为空，取出head位置元素
            int ret=data[head];
            head++;
            if(head>=data.length){
                head=0;
            }
            size--;
            //出队列成功之后，就唤醒put中的等待（之前满的时候要入，在wait）
            locker.notify();
            return ret;
        }
    }
}
public class Demo22 {
    private static MyBlockingQueue queue=new MyBlockingQueue();

    public static void main(String[] args) throws InterruptedException {
        //测试
//        MyBlockingQueue Queue=new MyBlockingQueue();
//        Queue.put(1);
//        Queue.put(2);
//        Queue.put(3);
//        Queue.put(4);
//        int ret= Queue.take();
//        System.out.println(ret);//打印1
//        ret= Queue.take();
//        System.out.println(ret);//2
//        ret= Queue.take();
//        System.out.println(ret);//3
//        ret= Queue.take();
//        System.out.println(ret);//4
//        ret= Queue.take();
//        System.out.println(ret);//一直等待，不结束进程

        //实现一个简单的生产者消费者模型

        //生产者
        Thread producer=new Thread(()->{
            int num=0;
           while(true) {
               try {
                   System.out.println("生产了"+num);
                   queue.put(num);
                   num++;
                   Thread.sleep(1000);
                   //通过sleep让生产者生产的慢一些，这样消费者就可以跟着生产者的步伐走（基本上就是生产一个消费一个）
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        producer.start();

        //消费者
        Thread customer=new Thread(()->{
           while(true){
               try {
                   int num= queue.take();
                   System.out.println("消费了"+num);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        customer.start();
    }
}
